﻿using GraphSharp.Algorithms.Layout;
using GraphSharp.Algorithms.Layout.Simple.Tree;
using GraphSharp.Controls;
using QuickGraph;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using WPFExtensions.Controls;

namespace LogAnalizer
{
    /// <summary>
    /// Interaction logic for GraphControl.xaml
    /// </summary>
    public partial class GraphControl : UserControl
    {
        #region Fields

        private BidirectionalGraph<VertexControl, IEdge<VertexControl>> graph;
        private VertexGraphLayout layout;
        private ZoomControl zoom;
        private int current = 0;
        private List<string> activeRouting;

        #endregion Fields 

        public List<LogMessage> Log { get; set; }

        public GraphControl()
        {
            InitializeComponent();

            activeRouting = new List<string>();

            layout = new VertexGraphLayout();
            layout.IsAnimationEnabled = false;
            layout.LayoutAlgorithmType = "Circular";
            zoom = new ZoomControl();
            zoom.Content = layout;
            grid.Children.Add(zoom);

            graph = new BidirectionalGraph<VertexControl, IEdge<VertexControl>>();
            layout.Graph = graph;

            //VertexControl vertex = new VertexControl();
            //vertex.Vertex = "0";
            //graph.AddVertex(vertex);

            //VertexControl vertex1 = new VertexControl();
            //vertex1.Vertex = "1";
            //graph.AddVertex(vertex1);

            //Edge<VertexControl> edge = new Edge<VertexControl>(vertex1, vertex);
            //graph.AddEdge(edge);
        }

        public void Add()
        {
            VertexControl vertex = new VertexControl();
            vertex.Vertex = graph.VertexCount.ToString();
            
            var v = graph.Vertices.First(x => x.Vertex.Equals((graph.VertexCount-1).ToString()));
            graph.AddVertex(vertex);

            Edge<VertexControl> edge = new Edge<VertexControl>(vertex, v);

            graph.AddEdge(edge);
        }

        //public void Next()
        //{
            //var l = Log[current];
            //if (l.Msg.Contains("Start") && l.To.Equals("akka://System/user/1"))
            //{
            //    VertexControl v = new VertexControl();
            //    v.Vertex = l.To;
            //    this.graph.AddVertex(v);
            //}
            //else if (l.Msg.Contains("Join"))
            //{
            //    var v = this.graph.Vertices.FirstOrDefault(x => x.Vertex.Equals(l.From));
            //    if (v == null)
            //    {
            //        v = new VertexControl();
            //        v.Vertex = l.From;
            //        this.graph.AddVertex(v);
            //    }
            //}
            //else if (l.Msg.Contains("Route"))
            //{
            //    var from = this.graph.Vertices.First(x => x.Vertex.Equals(l.From));
            //    var to = this.graph.Vertices.First(x => x.Vertex.Equals(l.To));
            //    this.graph.AddEdge(new Edge<VertexControl>(from, to));
            //}

            
            //current++;
        //}

        public void Next()
        {
            var msg = Log[current];
            if (msg.what.type.Equals("Start"))
            {
                //if (Log[current].to.Equals("akka://System/user/1"))
                //{
                    var v = new VertexControl();
                    v.Vertex = msg.to;
                    this.graph.AddVertex(v);
                //}
            }
            else if (msg.what.type.Equals("Join"))
            {
                if (activeRouting.Contains(msg.what.content.id))
                {
                    var from = this.graph.Vertices.First(x => x.Vertex.Equals(msg.from));
                    var to = this.graph.Vertices.First(x => x.Vertex.Equals(msg.to));
                    this.graph.AddEdge(new Edge<VertexControl>(from, to));
                }
                else 
                {
                    activeRouting.Add(msg.what.content.id);
                    //var from = new VertexControl();
                    //from.Vertex = msg.from;
                    //this.graph.AddVertex(from);

                    var from = this.graph.Vertices.First(x => x.Vertex.Equals(msg.from));
                    var to = this.graph.Vertices.First(x => x.Vertex.Equals(msg.to));
                    this.graph.AddEdge(new Edge<VertexControl>(from, to));
                }
            }
            else if (msg.what.type.Equals("JoinResponse"))
            {
                var from = this.graph.Vertices.First(x => x.Vertex.Equals(msg.from));
                var to = this.graph.Vertices.First(x => x.Vertex.Equals(msg.to));
                this.graph.AddEdge(new Edge<VertexControl>(from, to));
            }
            else if (msg.what.type.Equals("JoinDone"))
            {
                var from = this.graph.Vertices.First(x => x.Vertex.Equals(msg.from));
                var to = this.graph.Vertices.First(x => x.Vertex.Equals(msg.to));
                var edge = new Edge<VertexControl>(from, to);
                
                this.graph.AddEdge(edge);
            }

            current++;
        }
    }
}
